Watersheds
2.0 Overview
This analysis performs geomorphological processing of digital elevation models (DEMs) to extract critical watershed characteristics needed for hydrological modeling. We implement two complementary workflows for watershed delineation and hydraulic network analysis, comparing two approaches using flowdem (Martinsen, 2023) and whitebox (Wu & Brown, 2025a) packages with RichDEM (Barnes, 2016), GDAL 3.11 (contributors, 2020) and r-spatial (Hijmans, 2025; Pebesma & Bivand, 2023a, 2023b) libraries.
2.1 Declare AOIs
crs_master = sf::st_crs("EPSG:3857")
country = giscoR::gisco_get_countries(
country = "Malawi", resolution = "3") |>
sf::st_cast() |> sf::st_transform(crs_master)
lake = sf::st_read("../assets/inputs/lakes_site.shp") |>
sf::st_cast() |> sf::st_transform(crs_master)
NA Reading layer `lakes_site' from data source
NA `/Users/seamus/repos/map-templates/assets/inputs/lakes_site.shp'
NA using driver `ESRI Shapefile'
NA Simple feature collection with 1 feature and 22 fields
NA Geometry type: POLYGON
NA Dimension: XY
NA Bounding box: xmin: 35.6 ymin: -15.5 xmax: 35.9 ymax: -15
NA Geodetic CRS: WGS 84
bbox = lake |>
sf::st_buffer(dist = 60000) |>
sf::st_bbox() |>
sf::st_as_sfc() |>
sf::st_sf()
# Interactive map mode: "view"
tmap::tmap_mode("view")
tmap::tm_shape(country) + tmap::tm_borders(lwd=1, col= "green") +
tmap::tm_shape(bbox) + tmap::tm_borders(lwd=2, col= "orange") +
tmap::tm_shape(lake) + tmap::tm_borders(lwd=2, col= "blue") +
tmap::tm_basemap("Esri.WorldImagery")Figure 2a: Interactive map illustrating layout of area of interest polygons (AOI)
2.2 Download DEM
We acquired elevation data using the elevatr package (Hollister et al., 2023) that accesses via Amazon Web Services Terrain Tiles and the Open Topography Global DEM API collections of global digital elevation models including SRTMGL3, SRTMGL1, AW3D30, and SRTM15Plus. Depending on source, OSM’s Slippy Tiling syntax1 is used where zoom represents number of vertical tiles counting from top-left corner in a Peudo-Mercator grid (EPSG:3857). At lower latitudes, setting parameters to zoom=11 should return a data resolution of 3-arc-seconds (76m at 0°Lat). This allows us to then resample to a standardized 100m grid, which is useful for downstream metrics during watershed analysis. To limit dependency conflicts, a crs_master variable was derived above and applied below going forward.
# z = 12: 1-Arc Second Resolution
# z = 11: 3-Arc Second Resolution
# z = 10: 5-Arc Second Resolution
dem = elevatr::get_elev_raster(bbox, z=10, clip="locations") |> terra::rast()
names(dem) = "elevation"
dem_100m = stars::st_warp(
stars::st_as_stars(dem),
cellsize=100, crs=sf::st_crs(crs_master)) |>
terra::rast()
# Outputs
terra::writeRaster(dem_100m, overwrite = TRUE,
"../assets/TIF/dem_chilwa_00_raw.tif")2.3 Workflow in flowdem
The flowdem package (Martinsen, 2023) provides a streamlined R interface to RichDEM library, offering computationally efficient implementations of depression breaching, filling, and flow routing operations. While the WhiteboxTools workflow below (Section 2.3) provides more comprehensive control over individual processing steps, the flowdem approach enables rapid exploratory analysis through integrated functions that combine multiple operations. This “quick and efficient” methodology is particularly valuable for initial watershed characterization and iterative parameter testing.
We present the flowdem workflow as a complementary approach demonstrating that multiple algorithmic implementations can yield consistent watershed boundaries when applied to the same study system. Comparing outputs from both flowdem and whitebox packages also allows for validation of challenging data tasks such as endorheic basin delineation.
Hydraulic Conditioning
RichDEM’s depression handling implements priority-flood algorithms (Barnes et al., 2014; Barnes, 2016) that efficiently process large DEMs through optimized queue-based operations. The flowdem::breach() function carves minimal-depth channels through depressions, while flowdem::fill() with epsilon gradient (epsilon = TRUE) ensures continuous downstream flow by adding infinitesimal increments to flat areas. This combined approach removes topological barriers to flow routing while preserving the computational efficiency advantages of the RichDEM implementation.
The epsilon filling parameter adds small elevation increments (typically 10⁻⁶ to 10⁻⁴ m) to ensure strict monotonic descent along flow paths, preventing ambiguous flow directions in perfectly flat terrain common to marshland environments. This is varies slightly to the WhiteboxTools flat_increment parameter, though both achieve similar outcomes through slightly different numerical implementations.
# Inputs
dem_100m = terra::rast("../assets/TIF/dem_chilwa_00_raw.tif")
# Apply breaching & filling to depressions & flats
dem_breach = flowdem::breach(dem_100m)
dem_fill = flowdem::fill(dem_breach, epsilon=T)
# Visualize hydraulic conditioning
dem_breach_diff <- dem_100m - dem_breach
dem_breach_diff[dem_breach_diff == 0] <- NA
dem_fill_diff <- dem_100m - dem_fill
dem_fill_diff[dem_fill_diff == 0] <- NA
tmap::tmap_mode("plot")
tmap::tm_shape(dem_breach_diff) + tmap::tm_raster(col.scale=tm_scale_continuous(
values = hcl.colors(50, rev = TRUE),midpoint = 0), col.legend = tm_legend(title="")) +
tmap::tm_scalebar(position=c("RIGHT", "BOTTOM"), text.size = .5) +
tmap::tm_compass(color.dark="gray60",text.color="gray60",position=c("RIGHT", "top")) +
tmap::tm_graticules(lines=T,labels.rot=c(0,90),lwd=0.2) +
tmap::tm_title("Effects of Breaching", size=.8) -> tm_breach
tmap::tm_shape(dem_fill_diff) + tmap::tm_raster(col.scale = tm_scale_continuous(
values = hcl.colors(50, rev = TRUE),midpoint = 0), col.legend = tm_legend(title="")) +
tmap::tm_scalebar(position=c("RIGHT", "BOTTOM"), text.size = .5) +
tmap::tm_compass(color.dark="gray60",text.color="gray60",position=c("RIGHT", "top")) +
tmap::tm_graticules(lines=T,labels.rot=c(0,90),lwd=0.2) +
tmap::tm_title("Effects of Filling", size=.8) -> tm_fill
tmap::tmap_arrange(tm_breach, tm_fill, nrow=1)
# Outputs
terra::writeRaster(dem_breach, overwrite = TRUE,
"../assets/TIF/dem_chilwa_01_breached.tif")
terra::writeRaster(dem_fill, overwrite = TRUE,
"../assets/TIF/dem_chilwa_02_filled.tif")
Flow Accumulation
Flow routing follows the D8 algorithm (O’Callaghan & Mark, 1984) implemented through RichDEM’s optimized structures. The flowdem::dirs() function calculates flow direction pointers, which are then used as input to compute flow accumulation. This follows familiar two-step process of other workflows, but executes using a more memory-efficient function often useful when importing large raster and point cloud datasets.
The Flow accumulation values represent the number of upstream cells contributing flow to each location, identical in interpretation to WhiteboxTools outputs. At 100m resolution, each cell represents 0.01 km² (1 hectare) of contributing area, enabling direct conversion between cell counts and drainage area in km².
#|warning: false
#|message: false
#|error: false
#|eval: false
#|echo: true
#|comment: NA
# Inputs
dem_breach = terra::rast("../assets/TIF/dem_chilwa_01_breached.tif")
dem_fill = terra::rast("../assets/TIF/dem_chilwa_02_filled.tif")
# D8 flow direction + accumulation from filled DEM
dem_dir <- flowdem::dirs(dem_fill, mode = "d8")
dem_acc <- flowdem::accum(dem_dir, mode = "d8")
# Verify flow accumulation statistics
cat("Flow accumulation summary (flowdem):\n")
## Flow accumulation summary (flowdem):
cat("Minimum:", min(values(dem_acc), na.rm = TRUE),"cells\n")
## Minimum: 1 cells
cat("Median:", median(values(dem_acc), na.rm =TRUE), "cells\n")
## Median: 1 cells
cat("Maximum:", max(values(dem_acc), na.rm= TRUE), "cells\n")
## Maximum: 5017 cells
cat("Max contributing area:", round(max(values(
dem_acc), na.rm = TRUE) * 0.01, 1), "km²\n")
## Max contributing area: 50.2 km²
terra::writeRaster(dem_dir, overwrite=T,
"../assets/TIF/dem_chilwa_03_flow_direction.tif")
terra::writeRaster(dem_acc, overwrite=T,
"../assets/TIF/dem_chilwa_04_flow_accumulation.tif")
# Visual check
tmap::tmap_mode("view")
tmap::tm_shape(dem_acc) + tmap::tm_raster(
values="OrRd", title = "D8 Flow Accumulation",
breaks = c(1, 2, 3, 5, 10, 50, 100, 1000, 1200000),
labels = c("1-2", "2-3", "3-5", "5-10", "10-50", "50-100", "100-1K", ">1K")) +
tmap::tm_shape(lake) + tmap::tm_borders(col = "turquoise", lwd = 2) +
tmap::tm_layout(legend.text.size = 0.8, legend.title.size = 1)2.4 Watershed Delineation
The flowdem::watershed() function identifies all cells that drain to a specified feature, in this case, the Lake Chilwa boundary polygon. This approach differs from pour-point-based methods by using the entire lake perimeter as the drainage terminus, automatically capturing all flow paths converging on the water body. For endorheic systems where the terminal sink is spatially extensive (Lake Chilwa spans ~60 km N-S), this polygon-based approach may be more robust than single-point methods, as it captures multiple convergent flow paths around the lake’s perimeter.
The resulting watershed polygon represents the complete catchment area draining to Lake Chilwa through surface flow pathways identified by the D8 algorithm. Post-processing converts the raster watershed output to vector format for integration with other spatial datasets and area calculations.
# Inputs
dem_dir = terra::rast("../assets/TIF/dem_chilwa_03_flow_direction.tif")
dem_acc = terra::rast("../assets/TIF/dem_chilwa_04_flow_accumulation.tif")
# Delineate extent of watershed drainage area
watershed = flowdem::watershed(dem_dir, lake) |>
terra::as.polygons() |>
sf::st_as_sf()
# Visual check
tmap::tmap_mode("view")
tmap::tm_shape(dem_acc) + tmap::tm_raster(
values="OrRd", title = "D8 Flow Accumulation",
breaks = c(1, 2, 3, 5, 10, 50, 100, 1000, 1200000),
labels = c("1-2", "2-3", "3-5", "5-10", "10-50", "50-100", "100-1K", ">1K")) +
tmap::tm_shape(watershed) + tmap::tm_borders(col = "royalblue", lwd = 2) +
tmap::tm_shape(lake) + tmap::tm_borders(col = "turquoise", lwd = 2) +
tmap::tm_layout(legend.text.size = 0.8, legend.title.size = 1)
# Outputs
sf::st_write(watershed, "../assets/SHP/watershed_chilwa_05_flowdem.shp", delete_dsn=T)
NA Deleting source `../assets/SHP/watershed_chilwa_05_flowdem.shp' using driver `ESRI Shapefile'
NA Writing layer `watershed_chilwa_05_flowdem' to data source
NA `../assets/SHP/watershed_chilwa_05_flowdem.shp' using driver `ESRI Shapefile'
NA Writing 1 features with 1 fields and geometry type Multi Polygon.2.5 Workflow in whitebox
Lake Chilwa represents a critical challenge for standard watershed delineation as an endorheic, closed basin where water accumulates through surface inflow and evaporation without surface outflow. Traditional hydrological algorithms (O’Callaghan & Mark, 1984) assume exorheic drainage systems with defined pour points where water exits the catchment. For endorheic systems, we adapted this workflow principally by first estimating terminal sink points near to maximum flow values within the lake basin to compute drainages of internal sub-basins and delineating the watershed outwards. Implementation steps were as follows:
- Hydraulic breaching and filling
- D8 Flow direction and accumulation
- Depression network characterization,
- Derive terminal drainage points,
- Delineate watershed,
- Stream network classification.
Hydraulic Conditioning
Digital elevation models contain spurious depressions and flat areas arising from data acquisition artifacts, interpolation errors, and measurement precision limitations (Lindsay, 2016a). Artifacts disrupt continuous flow path connectivity essential for watershed delineation. Hydraulic conditioning removes these features while preserving genuine topographic depressions such as Lake Chilwa’s endorheic basin.
We applied depression breaching (Lindsay, 2016a) fitted with minimal-cost pathways and depression gradients (<3m depth) while preserving the primary lake basin. This approach removes DEM artifacts more conservatively without artificially draining the local system.
We applied depression filling using the Wang & Liu algorithm (Wang & Liu, 2006) to smooth remaining flat areas through scan-line method specifically suited to low-relief terrain. The combined breach-then-fill strategy balances computational efficiency with preservation of hydrologically meaningful features
# 1a. Conservative breaching of shallow depressions (<3m)
# while preserving the primary Lake Chilwa basin
whitebox::wbt_breach_depressions(
dem = "dem_chilwa_00_raw.tif",
output = "dem_chilwa_11_breached_flat.tif",
wd = "../assets/TIF/",
max_depth = 3, # Only breach shallow artifacts
flat_increment = 0.001
)
# 1b. Depression filling using Wang & Liu (2006) algorithm
# Optimized for flat terrain typical of marshlands
whitebox::wbt_fill_depressions_wang_and_liu(
dem = "dem_chilwa_11_breached_flat.tif",
output= "dem_chilwa_12_filled_wang.tif",
wd = "../assets/TIF/"
)
# 1c. Quantify conditioning effects
dem_breach = terra::rast("../assets/TIF/dem_chilwa_11_breached_flat.tif")
dem_filled = terra::rast("../assets/TIF/dem_chilwa_12_filled_wang.tif")
depression_effect <- dem_filled - dem_breach
breach_effect = dem_100m - dem_breach
fill_effect = dem_filled - dem_breach
total_effect = dem_filled - dem_100m
breach_effect[breach_effect == 0] <- NA
fill_effect[fill_effect == 0] <- NA
total_effect[total_effect == 0] <- NA
total_log <- log10(total_effect + 0.01) # +0.01 to handle small values
# Visualize hydraulic conditioning
tmap::tmap_mode("plot")
tmap::tm_shape(breach_effect) + tmap::tm_raster(col.scale = tm_scale_continuous(
values = hcl.colors(50, rev = T),midpoint=0),col.legend=tm_legend(title="")) +
tmap::tm_scalebar(position=c("RIGHT", "BOTTOM"), text.size = .5) +
tmap::tm_compass(color.dark="gray60",position=c("RIGHT", "top")) +
tmap::tm_graticules(lines=T,labels.rot=c(0,90),lwd=0.2) +
tmap::tm_title("Effects of Breaching", size=.8) -> tm_breach
tmap::tm_shape(fill_effect) + tmap::tm_raster(col.scale = tm_scale_continuous(
values = hcl.colors(50, rev = T),midpoint=0),col.legend=tm_legend(title="")) +
tmap::tm_scalebar(position=c("RIGHT", "BOTTOM"), text.size = .5) +
tmap::tm_compass(color.dark="gray60",position=c("RIGHT", "top")) +
tmap::tm_graticules(lines=T,labels.rot=c(0,90),lwd=0.2) +
tmap::tm_title("Effects of Filling", size=.8) -> tm_fill
tmap::tmap_arrange(tm_breach, tm_fill, nrow=1)
tmap::tmap_mode("view")
tmap::tm_shape(breach_effect) + tmap::tm_raster(
palette = "Blues", title = "Depth (m)", style = "cont") +
tmap::tm_shape(fill_effect) + tmap::tm_raster(
values = "Oranges", title = "Depth (m)", style = "cont") +
tmap::tm_shape(total_effect) + tmap::tm_raster(
values = "YlOrRd", title = "Depth (m)", style = "cont") +
tmap::tm_shape(lake) + tmap::tm_borders(col = "red", lwd = 1.5) +
tmap::tm_layout(main.title = "Effects of Breaching")
# Save for later
terra::writeRaster(depression_effect, overwrite=T,
"../assets/TIF/dem_chilwa_13_depression_effects.tif")
terra::writeRaster(breach_effect, overwrite = T,
"../assets/TIF/dem_chilwa_11_breach_effect.tif")
terra::writeRaster(fill_effect, overwrite = T,
"../assets/TIF/dem_chilwa_12_fill_effect.tif")
terra::writeRaster(total_effect, overwrite = T,
"../assets/TIF/dem_chilwa_13_total_effect.tif")
Flow Accumulation
Flow accumulation was computed using the D8 single-flow-direction algorithm (O’Callaghan & Mark, 1984) via the whitebox function wbt_d8_flow_accumulation() (Lindsay, 2016b; Wu & Brown, 2025b). The algorithm routes flow from each cell to its steepest downslope neighbor among eight adjacent cells. Flow accumulation values represent the number of upstream cells contributing flow to each location. At 100m spatial resolution, 1 cell = 0.01 km² contributing area.
# 2a. Calculate D8 flow direction
whitebox::wbt_d8_pointer(
dem = "dem_chilwa_12_filled_wang.tif",
output = "dem_chilwa_13_flow_direction_D8.tif",
wd = "../assets/TIF/"
)
# 2b. Calculate flow accumulation
# Output units: number of upstream cells contributing flow
# At 100m resolution: 1 cell = 0.01 km² contributing area
whitebox::wbt_d8_flow_accumulation(
input = "dem_chilwa_13_flow_direction_D8.tif",
output= "dem_chilwa_14_flow_accumulation_D8.tif",
wd = "../assets/TIF/",
pntr = T
)# Visual check
dem_acc = terra::rast("../assets/TIF/dem_chilwa_14_flow_accumulation.tif")
tmap::tmap_mode("view")
tmap::tm_shape(dem_acc) + tmap::tm_raster(
values="OrRd", title = "D8 Flow Accumulation",
breaks = c(1, 2, 3, 5, 10, 50, 100, 1000, 1200000),
labels = c("1-2", "2-3", "3-5", "5-10", "10-50", "50-100", "100-1K", ">1K")) +
tmap::tm_shape(lake) + tmap::tm_borders(col = "turquoise", lwd = 2) +
tmap::tm_layout(legend.text.size = 0.8, legend.title.size = 1)Depression Analysis
Endorheic basins are characterized by internal drainage networks where water accumulates in topographic depressions without surface outflow. We quantified two complementary metrics to characterize Lake Chilwa’s depression structure:
- depth in sink, measuring the vertically from cell to spillover point,
- topographic wetness index (TWI), indicating locations prone to water accumulation based on upslope contributing area and local slope.
Depth in sink analysis was performed on the raw (unconditioned) DEM to preserve actual depression depths, while TWI calculation used the hydrologically conditioned DEM and flow accumulation to ensure topologically consistent flow routing. These metrics jointly identify the spatial extent and hydrological characteristics of the endorheic system.
# 3a. Calculate depth within depressions using raw
# or unbreached DEM to measure depth below spillover points
whitebox::wbt_depth_in_sink(
dem = "dem_chilwa_00_raw.tif",
output = "dem_chilwa_15_sink_depth.tif",
wd = "../assets/TIF/",
zero_background = F
)
# 3b. Calculate topographic wetness index to support
# delineation of marshland in marginal zones
whitebox::wbt_wetness_index(
sca = "dem_chilwa_14_flow_accumulation_D8.tif",
slope = "dem_chilwa_12_filled_wang.tif",
output = "dem_chilwa_16_wetness_index.tif",
wd = "../assets/TIF/"
)
sink_depth <- terra::rast("../assets/TIF/dem_chilwa_15_sink_depth.tif")
wetness_idx <- terra::rast("../assets/TIF/dem_chilwa_16_wetness_index.tif")
flow_accum <- terra::rast("../assets/TIF/dem_chilwa_14_flow_accumulation_D8.tif")
tmap::tmap_mode("view")
tmap::tm_shape(sink_depth) + tmap::tm_raster(values = "Blues",
alpha=0.7, title = "Sink Depth (m)", style = "quantile", n=7) +
tmap::tm_shape(wetness_idx) + tmap::tm_raster(values="YlGnBu",
alpha=0.5, title="Wetness Index", style = "quantile", n=7) +
tmap::tm_shape(lake) + tmap::tm_borders(col = "turquoise", lwd = 2) +
tmap::tm_layout(legend.text.size = 0.8, legend.title.size = 1) +
tmap::tm_basemap("Esri.WorldImagery")
par(mfrow = c(1, 2))
hist(sink_depth[sink_depth <= 25], breaks = 30,
main = "Depths 0-10m", xlab = "Depth (m)", col = "steelblue")
hist(values(wetness_idx), breaks = 50, xlab = "TWI Value",
main = "Distribution of Wetness Index", col = "darkgreen")
Terminal Pour Points
Standard watershed delineation algorithms require pour points (outlet locations) where accumulated flow exits the drainage system. For endorheic basins lacking surface outflow, we identified terminal drainage points at locations of maximum flow accumulation within the lake basin, representing the ultimate destination of all surface drainage (Lehner et al., 2022; Zhang et al., 2020) (Li et al., 2025).
Terminal points were identified through interactive digitization using flow accumulation as reference. We tested both single-point and multi-point configurations to assess sensitivity of watershed delineation to pour point placement in flat terrain. Points were placed at the lake center where flow accumulation exceeds 1 million cells, confirming successful convergence of watershed-scale drainage .
# Assign terminal sink points near high flow accumulation
outlets = mapedit::editMap(mapview::mapView(dem_acc))
outlets = outlets$all |> # convert to sf
sf::st_transform(crs_master) |>
dplyr::select(geometry)
outlets$id <- "chilwa_drainage_terminus_single"
# Add terminal sink points to improve watershed delineation
outlets_add = mapedit::editMap(mapview::mapView(dem_acc))
outlets_add = outlets_add$all |> # convert to sf
sf::st_transform(crs_master) |>
dplyr::select(geometry)
outlets_add$id <- "chilwa_drainage_terminus_multiple"
# Visualize & save points for reproducibility
sf::st_write(outlets, "../assets/SHP/outlets.shp", delete_layer=T, quiet=T)
sf::st_write(outlets_add, "../assets/SHP/outlets_multiple.shp", delete_layer=T)
dem_acc = terra::rast("../assets/TIF/dem_chilwa_14_flow_accumulation.tif")
tmap::tm_shape(dem_acc) + tmap::tm_raster(values="brewer.reds") +
tmap::tm_shape(lake) + tmap::tm_borders(col="lightblue") +
tmap::tm_shape(outlets) + tmap::tm_symbols(shape="id",lwd=2)2.6 Streams Delineation
# Stream Classification
whitebox::wbt_extract_streams(
flow_accum= "dem_chilwa_14_flow_accumulation_D8.tif",
output = "dem_chilwa_18_streams_sensitive.tif",
wd = "../assets/TIF/",
zero_background = T,
threshold = 25,
)
whitebox::wbt_remove_short_streams(
d8_pntr = "dem_chilwa_14_flow_direction_D8.tif", # flow direction
streams = "dem_chilwa_18_streams_sensitive.tif",
output = "dem_chilwa_19_streams_d8.tif",
wd = "../assets/TIF/",
min_length= 200,
)
whitebox::wbt_find_main_stem(
d8_pntr = "dem_chilwa_14_flow_direction_D8.tif",
streams = "dem_chilwa_19_streams_d8.tif",
output = "dem_chilwa_20_streams_trunk.tif",
wd = "../assets/TIF/"
)
whitebox::wbt_raster_streams_to_vector(
streams = "dem_chilwa_20_streams_trunk.tif",
d8_pntr = "dem_chilwa_14_flow_direction_D8.tif",
output = "../assets/SHP/streams_chilwa.shp",
wd = "../assets/TIF/"
)# Inputs
streams_sf = sf::st_read("../assets/SHP/streams_chilwa.shp")
NA Reading layer `streams_chilwa' from data source
NA `/Users/seamus/repos/map-templates/assets/SHP/streams_chilwa.shp'
NA using driver `ESRI Shapefile'
NA Simple feature collection with 266 features and 2 fields
NA Geometry type: LINESTRING
NA Dimension: XY
NA Bounding box: xmin: 3900000 ymin: -1810000 xmax: 4050000 ymax: -1630000
NA CRS: NA
dem_filled = terra::rast("../assets/TIF/dem_chilwa_12_filled_wang.tif")
sf::st_crs(streams_sf) = 3857
# Visualize
tmap::tm_shape(dem_filled) + tmap::tm_raster(palette = "Greens") +
tmap::tm_shape(lake) + tmap::tm_borders(col = "turquoise", lwd = 2) +
tmap::tm_shape(streams_sf) + tmap::tm_lines(col = "steelblue") +
tmap::tm_layout(legend.text.size = 0.8, legend.title.size = 1)crs_master = "EPSG:3005"
island_shoreline = sf::st_read("../assets/SHP/island_shoreline.shp", quiet=T)
# z = 12: 1-Arc Second
# z = 11: 3-Arc Second
# z = 10: 5-Arc Second
dem_7arc = elevatr::get_elev_raster(island_shoreline, z=9,clip="locations")|>
terra::rast()|>
terra::crop(terra::vect(island_shoreline)) |>
terra::project(crs_master)
#Process DEM by breaching & filling depressions & flats
dem_condt_7arc = dem_7arc |>
flowdem::breach() |>
flowdem::fill(epsilon=T)
#flowdem::fill_basins() # costal basins
# Calculate flow direction & accumulation
dem_dir_7arc = dem_condt_7arc |> flowdem::dirs(mode="d8")
dem_dir_5arc = dem_condt_5arc |> flowdem::dirs(mode="d8")
dem_acc_7arc = dem_dir_7arc |> flowdem::accum(mode="d8")
dem_acc_5arc = dem_dir_5arc |> flowdem::accum(mode="d8")
#tmap::tm_shape(dem) +
# tmap::tm_raster(
# col.scale = tm_scale_continuous(values = "viridis"),
# col.legend = tm_legend(title = "Elevation (m)", reverse = T)) +
# tmap::tm_graticules(lines = T, labels.rot = c(0, 90), lwd = 0.2) +
# tmap::tm_scalebar(position = c("LEFT", "BOTTOM"), text.size = 0.5) +
# tmap::tm_compass(color.dark="gray60",text.color="gray60")+
# tmap::tm_basemap("Esri.WorldImagery")
writeRaster(dem_condt_7arc, "../assets/TIF/dem_7arc_condt.tif", overwrite=T)
writeRaster(dem_condt_5arc, "../assets/TIF/dem_5arc_condt.tif", overwrite=T)
writeRaster(dem_dir_7arc, "../assets/TIF/dem_7arc_dir.tif", overwrite=T)
writeRaster(dem_dir_5arc, "../assets/TIF/dem_5arc_dir.tif", overwrite=T)
writeRaster(dem_acc_7arc, "../assets/TIF/dem_7arc_acc.tif", overwrite=T)
writeRaster(dem_acc_5arc, "../assets/TIF/dem_5arc_acc.tif", overwrite=T)2.7 Build 3D map
rivers_strahler = rivers_site |>
dplyr::mutate(
width = as.numeric(
ORD_FLOW
),
width = dplyr::case_when(
width == 3 ~ 16,
width == 4 ~ 14,
width == 5 ~ 12,
width == 6 ~ 10,
width == 7 ~ 6,
TRUE ~ 0
)
) |>
sf::st_as_sf() |>
sf::st_transform(crs = "epsg:4326")
h <- nrow(dem_site)
w <- ncol(dem_site)
dem_matrix = rayshader::raster_to_matrix(dem_site)
dem_matrix |>
rayshader:: height_shade() |>
rayshader::add_overlay(
rayshader::generate_line_overlay(
geometry = rivers_strahler,
extent = dem_site,
heightmap = dem_matrix,
color = "#387B9C",
linewidth = rivers_strahler$width,
data_column_width = "width"
), alphalayer = 1
) |>
rayshader::add_overlay(
rayshader::generate_line_overlay(
geometry = lakes_site,
extent = dem_site,
heightmap = dem_matrix,
color = "#387B9C"
), alphalayer = 1
) |>
rayshader::plot_3d(
dem_matrix,
zscale = 14,
solid = T,
shadow = T,
shadow_darkness = 2,
background = "white",
windowsize = c(600, 600),
zoom = 0.6,
phi = 40,
theta = 0
)2.8 Render 3D map
rayshader::render_highquality(
preview = T,
light = F,
lightdirection = c(135, 45),
lightcolor = c("white"),
lightaltitude = 25,
ambient_light = 0.1,
rotate_env = 0.4,
intensity_env = 0.85,
interactive = F,
parallel = T,
width = w,
height = h,
backgroundhigh="#FFFFFF",
backgroundlow="#FFFFFF"
)
Environment Setup
pacman::p_load(
"bslib",
"cli", "cols4all", "covr", "cowplot",
"dendextend", "digest", "DiagrammeR",
"dtwclust", "downlit",
"exactextractr", "elevatr",
"FNN", "future", "flowdem",
"gdalUtilities", "geojsonsf", "geos", "geodata",
"ggplot2", "ggstats","ggspatial", "ggmap",
"ggplotify", "ggpubr", "ggrepel", "giscoR",
"hdf5r", "httr", "httr2", "htmltools",
"jsonlite",
"leafem", "leaflet.providers", "libgeos",
"luz", "lwgeom", "leaflet", "leafgl",
"mapedit", "mapview", "maptiles",
"methods", "mgcv", "MPI",
"ncdf4", "nnet",
"openxlsx",
"parallel", "plotly", "proj4", "PROJ", "progress", "purrr",
"randomForest", "rasterVis", "raster",
"rayshader", "rayvertex",
"RColorBrewer", "rgl", "rmapshaper", "rsconnect",
"RStoolbox", "rts", "rgrass",
"s2", "sf", "scales", "spdep", "stars",
"stringr", "supercells",
"terra", "terrainr", "testthat", "traudem", "taudem",
"tidyverse", "tidyterra", "tools",
"tmap", "tmaptools", "terrainr",
"whitebox", "xgboost"
)
# bleeding edge installs
#remotes::install_github("lucarraro/traudem", force=T)
#pak::pkg_install("MPI")
#devtools::install_github("lucarraro/traudem")
#remotes::install_github("opengeos/whiteboxR", build=F)
#remotes::install_github("giswqs/whiteboxR")
#install.packages("easypackages")
# assign larger memory to tmap rendering
tmap::tmap_options(component.autoscale=F,
max.raster = c(plot=9500000, view=10000000)
)
# ----- Whitebox debugging ---- #
# whitebox doesnt like working with files in memory
# so we need to assign path to working directory
# whitebox::install_whitebox() # install whitebox and GRASS libraries
whitebox::wbt_init() # activate whitebox library in current directory
list.files("/usr/local/taudem/") # Check traudem.pkg installation
# traudem::taudem_sitrep() # Check traudem dependencies
# Ignore above message "Can't find `MoveOutletsToStrm`"
# ----- TauDEM d8 Check ---- #
# all(sapply(d8, file.exists))
# Expected result: [1] TRUE
# all(file.exists(unlist(d8)))
# Expected result: [1] TRUE
# all(map_lgl(d8, file.exists))
# Expected result: [1] TRUE
# can_register_taudem()
# Expected result: [1] TRUE
# Whitebox loaded tools: `print(wbt_list_tools())`
# Whitebox shortcuts : `print(wbt_help())`
# Whitebox version : `print(wbt_version())`
# Whitebox tool guide: `print(wbt_tool_help("lidar_info"))`\
# Whitebox parameter guide: `print(wbt_tool_parameters("slope"))`
mapviewOptions(fgb = FALSE)
sf::sf_use_s2(use_s2 = FALSE)Runtime Log
devtools::session_info()
## ─ Session info ───────────────────────────────────────────
## setting value
## version R version 4.3.0 (2023-04-21)
## os macOS 15.7.1
## system aarch64, darwin20
## ui X11
## language (EN)
## collate en_US.UTF-8
## ctype en_US.UTF-8
## tz America/Vancouver
## date 2025-11-01
## pandoc 3.8 @ /opt/local/bin/ (via rmarkdown)
## quarto 1.7.33 @ /usr/local/bin/quarto
##
## ─ Packages ───────────────────────────────────────────────
## package * version date (UTC) lib source
## abind * 1.4-8 2024-09-12 [1] CRAN (R 4.3.3)
## backports 1.5.0 2024-05-23 [1] CRAN (R 4.3.3)
## base64enc 0.1-3 2015-07-28 [1] CRAN (R 4.3.3)
## bit 4.6.0 2025-03-06 [1] CRAN (R 4.3.3)
## bit64 4.6.0-1 2025-01-16 [1] CRAN (R 4.3.3)
## bitops 1.0-9 2024-10-03 [1] CRAN (R 4.3.3)
## boot 1.3-32 2025-08-29 [1] CRAN (R 4.3.0)
## brew 1.0-10 2023-12-16 [1] CRAN (R 4.3.3)
## brio 1.1.5 2024-04-24 [1] CRAN (R 4.3.3)
## broom 1.0.8 2025-03-28 [1] CRAN (R 4.3.3)
## bslib * 0.9.0 2025-01-30 [1] CRAN (R 4.3.3)
## cachem 1.1.0 2024-05-16 [1] CRAN (R 4.3.3)
## callr 3.7.6 2024-03-25 [1] CRAN (R 4.3.3)
## car 3.1-3 2024-09-27 [1] CRAN (R 4.3.3)
## carData 3.0-5 2022-01-06 [1] CRAN (R 4.3.3)
## caret 7.0-1 2024-12-10 [1] CRAN (R 4.3.3)
## class 7.3-23 2025-01-01 [1] CRAN (R 4.3.3)
## classInt 0.4-11 2025-01-08 [1] CRAN (R 4.3.3)
## cli * 3.6.5 2025-04-23 [1] CRAN (R 4.3.3)
## clue 0.3-66 2024-11-13 [1] CRAN (R 4.3.3)
## cluster 2.1.8.1 2025-03-12 [1] CRAN (R 4.3.3)
## codetools 0.2-20 2024-03-31 [1] CRAN (R 4.3.1)
## colorspace 2.1-1 2024-07-26 [1] CRAN (R 4.3.3)
## cols4all * 0.9 2025-08-28 [1] CRAN (R 4.3.0)
## coro 1.1.0 2024-11-05 [1] CRAN (R 4.3.3)
## countrycode 1.6.1 2025-03-31 [1] CRAN (R 4.3.3)
## covr * 3.6.4 2023-11-09 [1] CRAN (R 4.3.1)
## cowplot * 1.2.0 2025-07-07 [1] CRAN (R 4.3.3)
## crayon 1.5.3 2024-06-20 [1] CRAN (R 4.3.3)
## crosstalk 1.2.2 2025-08-26 [1] CRAN (R 4.3.0)
## curl 7.0.0 2025-08-19 [1] CRAN (R 4.3.0)
## data.table 1.17.8 2025-07-10 [1] CRAN (R 4.3.3)
## DBI 1.2.3 2024-06-02 [1] CRAN (R 4.3.3)
## deldir 2.0-4 2024-02-28 [1] CRAN (R 4.3.3)
## dendextend * 1.19.1 2025-07-15 [1] CRAN (R 4.3.0)
## devtools 2.4.5 2022-10-11 [1] CRAN (R 4.3.0)
## DiagrammeR * 1.0.11 2024-02-02 [1] CRAN (R 4.3.1)
## dichromat 2.0-0.1 2022-05-02 [1] CRAN (R 4.3.3)
## digest * 0.6.37 2024-08-19 [1] CRAN (R 4.3.3)
## doParallel 1.0.17 2022-02-07 [1] CRAN (R 4.3.3)
## downlit * 0.4.4 2024-06-10 [1] CRAN (R 4.3.3)
## dplyr * 1.1.4 2023-11-17 [1] CRAN (R 4.3.1)
## dtw * 1.23-1 2022-09-19 [1] CRAN (R 4.3.3)
## dtwclust * 6.0.0 2024-07-23 [1] CRAN (R 4.3.3)
## e1071 1.7-16 2024-09-16 [1] CRAN (R 4.3.3)
## elevatr * 0.99.0 2023-09-12 [1] CRAN (R 4.3.0)
## ellipsis 0.3.2 2021-04-29 [1] CRAN (R 4.3.3)
## evaluate 1.0.5 2025-08-27 [1] CRAN (R 4.3.0)
## exactextractr * 0.10.0 2023-09-20 [1] CRAN (R 4.3.1)
## extrafont 0.19 2023-01-18 [1] CRAN (R 4.3.3)
## extrafontdb 1.0 2012-06-11 [1] CRAN (R 4.3.3)
## farver 2.1.2 2024-05-13 [1] CRAN (R 4.3.3)
## fastmap 1.2.0 2024-05-15 [1] CRAN (R 4.3.3)
## flexclust 1.5.0 2025-02-28 [1] CRAN (R 4.3.3)
## flowdem * 0.2 2025-09-14 [1] Github (KennethTM/flowdem@98cdb20)
## FNN * 1.1.4.1 2024-09-22 [1] CRAN (R 4.3.3)
## forcats * 1.0.0 2023-01-29 [1] CRAN (R 4.3.0)
## foreach 1.5.2 2022-02-02 [1] CRAN (R 4.3.3)
## Formula 1.2-5 2023-02-24 [1] CRAN (R 4.3.3)
## fs 1.6.6 2025-04-12 [1] CRAN (R 4.3.3)
## future * 1.67.0 2025-07-29 [1] CRAN (R 4.3.0)
## future.apply 1.20.0 2025-06-06 [1] CRAN (R 4.3.0)
## gdalUtilities * 1.2.5 2023-08-10 [1] CRAN (R 4.3.0)
## generics 0.1.4 2025-05-09 [1] CRAN (R 4.3.3)
## geodata * 0.6-2 2024-06-10 [1] CRAN (R 4.3.3)
## geojsonsf * 2.0.3 2022-05-30 [1] CRAN (R 4.3.3)
## geos * 0.2.4 2023-11-30 [1] CRAN (R 4.3.3)
## ggmap * 4.0.1 2025-04-07 [1] CRAN (R 4.3.3)
## ggplot2 * 3.5.2 2025-04-09 [1] CRAN (R 4.3.3)
## ggplotify * 0.1.2 2023-08-09 [1] CRAN (R 4.3.0)
## ggpubr * 0.6.1 2025-06-27 [1] CRAN (R 4.3.3)
## ggrepel * 0.9.6 2024-09-07 [1] CRAN (R 4.3.3)
## ggsignif 0.6.4 2022-10-13 [1] CRAN (R 4.3.0)
## ggspatial * 1.1.10 2025-08-24 [1] CRAN (R 4.3.0)
## ggstats * 0.10.0 2025-07-02 [1] CRAN (R 4.3.3)
## giscoR * 0.6.1 2025-08-11 [1] Github (rOpenGov/giscoR@adfed30)
## globals 0.18.0 2025-05-08 [1] CRAN (R 4.3.0)
## glue 1.8.0 2024-09-30 [1] CRAN (R 4.3.3)
## gower 1.0.2 2024-12-17 [1] CRAN (R 4.3.3)
## gridExtra 2.3 2017-09-09 [1] CRAN (R 4.3.3)
## gridGraphics 0.5-1 2020-12-13 [1] CRAN (R 4.3.3)
## gtable 0.3.6 2024-10-25 [1] CRAN (R 4.3.3)
## hardhat 1.4.2 2025-08-20 [1] CRAN (R 4.3.0)
## hdf5r * 1.3.12 2025-01-20 [1] CRAN (R 4.3.3)
## hexbin 1.28.5 2024-11-13 [1] CRAN (R 4.3.3)
## hms 1.1.3 2023-03-21 [1] CRAN (R 4.3.0)
## htmltools * 0.5.8.1 2024-04-04 [1] CRAN (R 4.3.3)
## htmlwidgets 1.6.4 2023-12-06 [1] CRAN (R 4.3.1)
## httpuv 1.6.16 2025-04-16 [1] CRAN (R 4.3.3)
## httr * 1.4.7 2023-08-15 [1] CRAN (R 4.3.0)
## httr2 * 1.2.1 2025-07-22 [1] CRAN (R 4.3.0)
## interp 1.1-6 2024-01-26 [1] CRAN (R 4.3.3)
## ipred 0.9-15 2024-07-18 [1] CRAN (R 4.3.3)
## iterators 1.0.14 2022-02-05 [1] CRAN (R 4.3.3)
## jpeg 0.1-11 2025-03-21 [1] CRAN (R 4.3.3)
## jquerylib 0.1.4 2021-04-26 [1] CRAN (R 4.3.3)
## jsonlite * 2.0.0 2025-03-27 [1] CRAN (R 4.3.3)
## KernSmooth 2.23-26 2025-01-01 [1] CRAN (R 4.3.3)
## knitr 1.50 2025-03-16 [1] CRAN (R 4.3.3)
## later 1.4.4 2025-08-27 [1] CRAN (R 4.3.0)
## lattice * 0.22-7 2025-04-02 [1] CRAN (R 4.3.3)
## latticeExtra 0.6-30 2022-07-04 [1] CRAN (R 4.3.3)
## lava 1.8.1 2025-01-12 [1] CRAN (R 4.3.3)
## lazyeval 0.2.2 2019-03-15 [1] CRAN (R 4.3.3)
## leafem * 0.2.5 2025-08-28 [1] CRAN (R 4.3.0)
## leafgl * 0.2.2 2024-11-13 [1] CRAN (R 4.3.3)
## leaflegend 1.2.1 2024-05-09 [1] CRAN (R 4.3.3)
## leaflet * 2.2.2 2024-03-26 [1] CRAN (R 4.3.1)
## leaflet.providers * 2.0.0 2023-10-17 [1] CRAN (R 4.3.3)
## leafpop 0.1.0 2021-05-22 [1] CRAN (R 4.3.0)
## leafsync 0.1.0 2019-03-05 [1] CRAN (R 4.3.0)
## libgeos * 3.11.1-3 2025-03-19 [1] CRAN (R 4.3.3)
## lifecycle 1.0.4 2023-11-07 [1] CRAN (R 4.3.3)
## listenv 0.9.1 2024-01-29 [1] CRAN (R 4.3.3)
## logger 0.4.0 2024-10-22 [1] CRAN (R 4.3.3)
## lubridate * 1.9.4 2024-12-08 [1] CRAN (R 4.3.3)
## luz * 0.5.0 2025-07-29 [1] CRAN (R 4.3.0)
## lwgeom * 0.2-14 2024-02-21 [1] CRAN (R 4.3.1)
## magrittr 2.0.4 2025-09-12 [1] CRAN (R 4.3.0)
## mapedit * 0.7.0 2025-04-20 [1] CRAN (R 4.3.3)
## maptiles * 0.10.0 2025-05-07 [1] CRAN (R 4.3.3)
## mapview * 2.11.2 2023-10-13 [1] CRAN (R 4.3.1)
## MASS 7.3-60.0.1 2024-01-13 [1] CRAN (R 4.3.1)
## Matrix 1.6-5 2024-01-11 [1] CRAN (R 4.3.1)
## memoise 2.0.1 2021-11-26 [1] CRAN (R 4.3.3)
## mgcv * 1.9-3 2025-04-04 [1] CRAN (R 4.3.0)
## microbenchmark 1.5.0 2024-09-04 [1] CRAN (R 4.3.3)
## mime 0.13 2025-03-17 [1] CRAN (R 4.3.3)
## miniUI 0.1.2 2025-04-17 [1] CRAN (R 4.3.3)
## ModelMetrics 1.2.2.2 2020-03-17 [1] CRAN (R 4.3.3)
## modeltools 0.2-24 2025-05-02 [1] CRAN (R 4.3.3)
## MPI * 0.1.0 2022-04-05 [1] CRAN (R 4.3.0)
## ncdf4 * 1.24 2025-03-25 [1] CRAN (R 4.3.3)
## nlme * 3.1-168 2025-03-31 [1] CRAN (R 4.3.3)
## nnet * 7.3-20 2025-01-01 [1] CRAN (R 4.3.3)
## openxlsx * 4.2.8 2025-01-25 [1] CRAN (R 4.3.3)
## pacman 0.5.1 2019-03-11 [1] CRAN (R 4.3.3)
## parallelly 1.45.1 2025-07-24 [1] CRAN (R 4.3.0)
## pillar 1.11.0 2025-07-04 [1] CRAN (R 4.3.3)
## pkgbuild 1.4.8 2025-05-26 [1] CRAN (R 4.3.3)
## pkgconfig 2.0.3 2019-09-22 [1] CRAN (R 4.3.3)
## pkgload 1.4.0 2024-06-28 [1] CRAN (R 4.3.3)
## plotly * 4.11.0 2025-06-19 [1] CRAN (R 4.3.3)
## plyr 1.8.9 2023-10-02 [1] CRAN (R 4.3.3)
## png 0.1-8 2022-11-29 [1] CRAN (R 4.3.3)
## prettyunits 1.2.0 2023-09-24 [1] CRAN (R 4.3.3)
## pROC 1.19.0.1 2025-07-31 [1] CRAN (R 4.3.0)
## processx 3.8.6 2025-02-21 [1] CRAN (R 4.3.3)
## prodlim 2025.04.28 2025-04-28 [1] CRAN (R 4.3.3)
## profvis 0.4.0 2024-09-20 [1] CRAN (R 4.3.3)
## progress * 1.2.3 2023-12-06 [1] CRAN (R 4.3.1)
## progressr 0.15.1 2024-11-22 [1] CRAN (R 4.3.3)
## PROJ * 0.6.0 2025-04-03 [1] CRAN (R 4.3.3)
## proj4 * 1.0-15 2025-03-21 [1] CRAN (R 4.3.3)
## promises 1.3.3 2025-05-29 [1] CRAN (R 4.3.3)
## proxy * 0.4-27 2022-06-09 [1] CRAN (R 4.3.3)
## ps 1.9.1 2025-04-12 [1] CRAN (R 4.3.3)
## purrr * 1.1.0 2025-07-10 [1] CRAN (R 4.3.0)
## R6 2.6.1 2025-02-15 [1] CRAN (R 4.3.3)
## randomForest * 4.7-1.2 2024-09-22 [1] CRAN (R 4.3.3)
## rappdirs 0.3.3 2021-01-31 [1] CRAN (R 4.3.3)
## raster * 3.6-32 2025-03-28 [1] CRAN (R 4.3.3)
## rasterVis * 0.51.6 2023-11-01 [1] CRAN (R 4.3.3)
## rayshader * 0.37.3 2024-02-21 [1] CRAN (R 4.3.1)
## rayvertex * 0.12.0 2025-02-03 [1] CRAN (R 4.3.3)
## RColorBrewer * 1.1-3 2022-04-03 [1] CRAN (R 4.3.3)
## Rcpp 1.1.0 2025-07-02 [1] CRAN (R 4.3.3)
## RcppParallel 5.1.11-1 2025-08-27 [1] CRAN (R 4.3.0)
## RCurl 1.98-1.17 2025-03-22 [1] CRAN (R 4.3.3)
## readr * 2.1.5 2024-01-10 [1] CRAN (R 4.3.1)
## recipes 1.3.1 2025-05-21 [1] CRAN (R 4.3.3)
## remotes 2.5.0 2024-03-17 [1] CRAN (R 4.3.3)
## reshape2 1.4.4 2020-04-09 [1] CRAN (R 4.3.0)
## rex 1.2.1 2021-11-26 [1] CRAN (R 4.3.3)
## rgl * 1.3.24 2025-06-25 [1] CRAN (R 4.3.3)
## rgrass * 0.5-2 2025-02-14 [1] CRAN (R 4.3.3)
## rlang 1.1.6 2025-04-11 [1] CRAN (R 4.3.3)
## rmapshaper * 0.5.0 2023-04-11 [1] CRAN (R 4.3.0)
## rmarkdown 2.29 2024-11-04 [1] CRAN (R 4.3.3)
## rpart 4.1.24 2025-01-07 [1] CRAN (R 4.3.3)
## rsconnect * 1.5.1 2025-08-28 [1] CRAN (R 4.3.0)
## RSpectra 0.16-2 2024-07-18 [1] CRAN (R 4.3.3)
## rstatix 0.7.2 2023-02-01 [1] CRAN (R 4.3.0)
## RStoolbox * 1.0.2.1 2025-02-03 [1] CRAN (R 4.3.3)
## rstudioapi 0.17.1 2024-10-22 [1] CRAN (R 4.3.3)
## rts * 1.1-14 2023-10-01 [1] CRAN (R 4.3.3)
## Rttf2pt1 1.3.12 2023-01-22 [1] CRAN (R 4.3.3)
## s2 * 1.1.9 2025-05-23 [1] CRAN (R 4.3.3)
## sass 0.4.10 2025-04-11 [1] CRAN (R 4.3.3)
## satellite 1.0.6 2025-08-21 [1] CRAN (R 4.3.0)
## scales * 1.4.0 2025-04-24 [1] CRAN (R 4.3.3)
## sessioninfo 1.2.3 2025-02-05 [1] CRAN (R 4.3.3)
## sf * 1.0-22 2025-08-25 [1] Github (r-spatial/sf@3660edf)
## shiny 1.11.1 2025-07-03 [1] CRAN (R 4.3.3)
## shinyjs 2.1.0 2021-12-23 [1] CRAN (R 4.3.0)
## shinyWidgets 0.9.0 2025-02-21 [1] CRAN (R 4.3.3)
## sp * 2.2-0 2025-02-01 [1] CRAN (R 4.3.3)
## spacesXYZ 1.6-0 2025-06-06 [1] CRAN (R 4.3.3)
## spData * 2.3.4 2025-01-08 [1] CRAN (R 4.3.3)
## spdep * 1.4-1 2025-08-31 [1] CRAN (R 4.3.0)
## stars * 0.6-8 2025-02-01 [1] CRAN (R 4.3.3)
## stringi 1.8.7 2025-03-27 [1] CRAN (R 4.3.3)
## stringr * 1.5.2 2025-09-08 [1] CRAN (R 4.3.0)
## supercells * 1.0.0 2024-02-11 [1] CRAN (R 4.3.1)
## survival 3.8-3 2024-12-17 [1] CRAN (R 4.3.3)
## svglite 2.2.1 2025-05-12 [1] CRAN (R 4.3.3)
## systemfonts 1.2.3 2025-04-30 [1] CRAN (R 4.3.3)
## terra * 1.8-60 2025-07-21 [1] CRAN (R 4.3.0)
## terrainr * 0.7.6 2025-07-25 [1] CRAN (R 4.3.0)
## testthat * 3.2.3 2025-01-13 [1] CRAN (R 4.3.3)
## textshaping 1.0.3 2025-09-02 [1] CRAN (R 4.3.0)
## tibble * 3.3.0 2025-06-08 [1] CRAN (R 4.3.3)
## tidyr * 1.3.1 2024-01-24 [1] CRAN (R 4.3.1)
## tidyselect 1.2.1 2024-03-11 [1] CRAN (R 4.3.1)
## tidyterra * 0.7.2 2025-04-14 [1] CRAN (R 4.3.3)
## tidyverse * 2.0.0 2023-02-22 [1] CRAN (R 4.3.0)
## timechange 0.3.0 2024-01-18 [1] CRAN (R 4.3.3)
## timeDate 4041.110 2024-09-22 [1] CRAN (R 4.3.3)
## tmap * 4.1 2025-05-12 [1] CRAN (R 4.3.3)
## tmaptools * 3.2 2025-01-13 [1] CRAN (R 4.3.3)
## torch 0.16.0 2025-08-21 [1] CRAN (R 4.3.0)
## traudem * 1.0.3 2025-10-28 [1] Github (lucarraro/traudem@a30c9c9)
## tzdb 0.5.0 2025-03-15 [1] CRAN (R 4.3.3)
## unifir 0.2.4 2024-02-01 [1] CRAN (R 4.3.3)
## units 0.8-7 2025-03-11 [1] CRAN (R 4.3.3)
## urlchecker 1.0.1 2021-11-30 [1] CRAN (R 4.3.3)
## usethis 3.1.0 2024-11-26 [1] CRAN (R 4.3.3)
## uuid 1.2-1 2024-07-29 [1] CRAN (R 4.3.3)
## V8 6.0.4 2025-06-04 [1] CRAN (R 4.3.3)
## vctrs 0.6.5 2023-12-01 [1] CRAN (R 4.3.3)
## viridis 0.6.5 2024-01-29 [1] CRAN (R 4.3.1)
## viridisLite 0.4.2 2023-05-02 [1] CRAN (R 4.3.3)
## visNetwork 2.1.2 2022-09-29 [1] CRAN (R 4.3.0)
## whitebox * 2.4.3 2025-10-28 [1] Github (opengeos/whiteboxR@294ea4b)
## withr 3.0.2 2024-10-28 [1] CRAN (R 4.3.3)
## wk 0.9.4 2024-10-11 [1] CRAN (R 4.3.3)
## xfun 0.53 2025-08-19 [1] CRAN (R 4.3.0)
## xgboost * 1.7.11.1 2025-05-15 [1] CRAN (R 4.3.3)
## XML 3.99-0.18 2025-01-01 [1] CRAN (R 4.3.3)
## xml2 1.4.0 2025-08-20 [1] CRAN (R 4.3.0)
## xtable 1.8-4 2019-04-21 [1] CRAN (R 4.3.3)
## xts * 0.14.1 2024-10-15 [1] CRAN (R 4.3.3)
## yaml 2.3.10 2024-07-26 [1] CRAN (R 4.3.3)
## yulab.utils 0.2.1 2025-08-19 [1] CRAN (R 4.3.0)
## zeallot 0.2.0 2025-05-27 [1] CRAN (R 4.3.3)
## zip 2.3.3 2025-05-13 [1] CRAN (R 4.3.3)
## zoo * 1.8-14 2025-04-10 [1] CRAN (R 4.3.3)
##
## [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
## * ── Packages attached to the search path.
##
## ──────────────────────────────────────────────────────────